﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using xKnight.Attacking.SimpleXss;
using xKnight.Attacking.Xss;
using xKnight.Data;
using xKnight.Models;

namespace xKnight.Attacking.EncodedXss 
{
    internal class EncodedXssAttackerAgent : SimpleXssAttackerAgent
    {

        #region Constructors

        public EncodedXssAttackerAgent(AttackingSharedReource sharedResource)
            :base(sharedResource)
        {
        }

        #endregion

        #region Interface

        #endregion

        #region Private Methods

        protected override string SendAttackVector(Form form, string attackContent)
        {
            try
            {
                EncodedXssAttackAnnounceItem announceItem = new EncodedXssAttackAnnounceItem(form.Action, form.Method,
                    AttackStatus.AttackStarted, SharedResource, "", DateTime.Now, 0, "آغاز درخواست", form.Webpage.Url);
                OnAgentAttackAnnounced(announceItem);

                HttpWebRequest request = null;

                if (form.Method == "get")
                    request = WebRequest.Create(form.Action + attackContent) as HttpWebRequest;
                else
                    request = WebRequest.Create(form.Action) as HttpWebRequest;

                request.Timeout = 100000;
                request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
                request.AllowAutoRedirect = true;
                request.KeepAlive = true;

                if (form.Method == "post")
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                    byte[] data = Encoding.UTF8.GetBytes(attackContent);
                    request.ContentLength = data.Length;
                    request.Method = "POST";

                    using (Stream stream = request.GetRequestStream())
                        stream.Write(data, 0, data.Length);
                }
                else
                    request.Method = "GET";

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if (HasCorrectResponce(response) && (response.ContentType.Contains("text/html")))
                    {
                        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                        {
                            string resp = sr.ReadToEnd();

                            announceItem = new EncodedXssAttackAnnounceItem(form.Action, form.Method, AttackStatus.AttackFinished, SharedResource, "", DateTime.Now
                                , (int)response.StatusCode, response.StatusDescription, form.Webpage.Url);
                            OnAgentAttackAnnounced(announceItem);

                            SharedResource.IncrementAttacks();
                            return resp;
                        }
                    }
                    else
                    {
                        announceItem = new EncodedXssAttackAnnounceItem(form.Action, form.Method, AttackStatus.AttackHalted, SharedResource, "", DateTime.Now
                          , (int)response.StatusCode, response.StatusDescription, form.Webpage.Url);

                        OnAgentAttackAnnounced(announceItem);
                        return null;
                    }
                }
            }
            catch (WebException ex)
            {
                HttpWebResponse response = ex.Response as HttpWebResponse;

                if (response != null)
                {
                    EncodedXssAttackAnnounceItem announceItem = new EncodedXssAttackAnnounceItem(form.Action, form.Method, AttackStatus.AttackHalted, SharedResource, "", DateTime.Now
                        , (int)response.StatusCode
                        , response.StatusDescription, form.Webpage.Url);
                    OnAgentAttackAnnounced(announceItem);
                }
                else
                {
                    EncodedXssAttackAnnounceItem announceItem = new EncodedXssAttackAnnounceItem(form.Action, form.Method, AttackStatus.AttackHalted, SharedResource, "", DateTime.Now
                        , -1, "پاسخی دریافت نشد", form.Webpage.Url);
                    OnAgentAttackAnnounced(announceItem);
                }
            }
            catch
            {
                EncodedXssAttackAnnounceItem announceItem = new EncodedXssAttackAnnounceItem(form.Action, form.Method, AttackStatus.AttackHalted, SharedResource, "", DateTime.Now
                    , -1, "پاسخی دریافت نشد", form.Webpage.Url);
                OnAgentAttackAnnounced(announceItem);
            }

            return null;

        }

        protected override string GetInjectionValue()
        {
            return "";
        }

        #endregion
    }
}
